Konwersja MBR <=> GPT
Kategoria: Artykuły, etykiety: mbr, konwersja, gpt, dysk
Dodany: 2014-01-04 16:54
(zmodyfikowany: 2014-01-11 01:52)
Przez: morfik
Wyświetleń: 24506
Od jakiegoś czasu nosiłem się z zamiarem utworzenia na swoim dysku tablicy partycji GPT. Problem w tym, że tam jest wgranych paręset GiB danych i nie mam gdzie tego upchnąć. Jedyne co mi wpadło do głowy to przekonwertowanie tablicy MBR na GPT. Nie żebym jakoś tego potrzebował, w końcu mam dysk 1,5TB ale tak z ciekawości chciałem zobaczyć czy da się to zrobić w sposób łatwy i bezproblemowy. No i dało się. W roli głównej wystąpił mój stary dysk (80GB) -- zrobiłem na nim 6 partycji, 3 zwykłe i 3 rozszerzone. Pierwsza partycja jest pod wina xp, druga to zaszyfrowany system linuxowy ale jak zwykle zapomniałem zostawić trochę miejsca na partycję /boot , a ta wylądowała na pozycji sda6. Partycja trzecia to niezaszyfrowany swap, a pozostałe dwie (5 i 7) to dwa zaszyfrowane voluminy, z których jeden celowo umieszczony na końcu dysku, drugi zaś na początku rozszerzonej partycji. Cel to przekonwertować tablicę partycji MBR na GPT (i vice versa) bez utraty danych.
Konwersja MBR -> GPT
Tak wygląda dysk widziany oczami parted (z uwzględnieniem wolnych przestrzeni):
(parted) print free
Model: ATA WDC WD800JB-00JJ (scsi)
Disk /dev/sda: 80,0GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Number Start End Size Type File system Flags
32,3kB 1049kB 1016kB Free Space
1 1049kB 31,5GB 31,5GB primary ntfs boot
2 31,5GB 43,0GB 11,5GB primary
3 43,0GB 44,1GB 1074MB primary linux-swap(v1)
4 44,1GB 80,0GB 36,0GB extended
5 44,1GB 54,6GB 10,5GB logical
6 54,6GB 65,0GB 10,5GB logical ext4 boot
7 65,0GB 80,0GB 15,0GB logical
80,0GB 80,0GB 56,8kB Free Space
By przeprowadzić bezproblemowo konwersję z MBR na GPT trzeba mieć troszeczkę wolnego miejsca na początku i na końcu dysku. Ile? Struktura GPT wygląda tak: 512 bajtowy MBR + 512bajtowy nagłówek GPT + 16 KiB głównej tablicy partycji. Łącznie daje to 34 sektory 512 bajtowe, co przekłada się na 34*512=17408 bajtów wolnego miejsca na początku dysku. Ale tablica partycji GPT ma jeszcze backup swojej zawartości, który jest zlokalizowany na końcu dysku i w jego skład wchodzi kopia głównej tablicy partycji -- 16 KiB oraz kopia nagłówka 1 sektor 512 bajtowy. Łącznie 33 sektory co daje 16896 bajtów potrzebnego miejsca na końcu dysku.
Obecnie większość narzędzi tworzących partycje na dysku ustawia równanie do 1MiB co przekłada się na 2048 wolnych sektorów na początku dysku, więc tutaj nie powinno być problemów ze spełnieniem wymagań pod GPT. Ale takie równanie do 1MiB może czasem zając resztę dysku. W moim przypadku, jak widać powyżej, zostało trochę wolnego miejsca -- 56,8kB. Także u mnie wszystko jest ok. W przypadku jednak gdyby partycja wypełniła dysk do końca, trzeba będzie ją skrócić.
By przekonwertować tablicę partycji odpalamy gdisk:
# gdisk /dev/sda
GPT fdisk (gdisk) version 0.8.5
Partition table scan:
MBR: MBR only
BSD: not present
APM: not present
GPT: not present
***************************************************************
Found invalid GPT and valid MBR; converting MBR to GPT format.
THIS OPERATION IS POTENTIALLY DESTRUCTIVE! Exit by typing 'q' if
you don't want to convert your MBR partitions to GPT format!
***************************************************************
Jak widać, gdisk wykrył, że ma do czynienia z tablicą partycji MBR. Konwertowanie polega na wpisaniu w:
Command (? for help): w
Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!
Do you want to proceed? (Y/N): y
OK; writing new GUID partition table (GPT) to /dev/sda.
The operation has completed successfully.
Sprawdzamy, czy faktycznie się przekonwertowało:
# gdisk /dev/sda
GPT fdisk (gdisk) version 0.8.5
Partition table scan:
MBR: protective
BSD: not present
APM: not present
GPT: present
Found valid GPT with protective MBR; using GPT.
Wygląda w porządku, teraz sprawdzamy układ partycji:
Command (? for help): p
Disk /dev/sda: 156299375 sectors, 74.5 GiB
Logical sector size: 512 bytes
Disk identifier (GUID): 526AC8D7-EEC8-4BA3-B654-31EF40528AF2
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 156299341
Partitions will be aligned on 2048-sector boundaries
Total free space is 8236 sectors (4.0 MiB)
Number Start (sector) End (sector) Size Code Name
1 2048 61442047 29.3 GiB 0700 Microsoft basic data
2 61442048 83970047 10.7 GiB 8300 Linux filesystem
3 83970048 86067199 1024.0 MiB 8200 Linux swap
5 86069248 106549247 9.8 GiB 8300 Linux filesystem
6 106551296 127031295 9.8 GiB 8300 Linux filesystem
7 127033344 156299263 14.0 GiB 8300 Linux filesystem
Czyli bez problemu proces się zakończył. Rzućmy jeszcze okiem na to jak wygląda struktura partycji w parted:
# parted /dev/sda
GNU Parted 2.3
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print free
Model: ATA WDC WD800JB-00JJ (scsi)
Disk /dev/sda: 80,0GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Number Start End Size File system Name Flags
17,4kB 1049kB 1031kB Free Space
1 1049kB 31,5GB 31,5GB ntfs Microsoft basic data msftdata
2 31,5GB 43,0GB 11,5GB Linux filesystem
3 43,0GB 44,1GB 1074MB linux-swap(v1) Linux swap
44,1GB 44,1GB 1049kB Free Space
5 44,1GB 54,6GB 10,5GB Linux filesystem
54,6GB 54,6GB 1049kB Free Space
6 54,6GB 65,0GB 10,5GB ext4 Linux filesystem
65,0GB 65,0GB 1049kB Free Space
7 65,0GB 80,0GB 15,0GB Linux filesystem
80,0GB 80,0GB 39,9kB Free Space
No tu już widać trochę różnic. Przede wszystkim są dziury. W miejscu gdzie zaczynały się dyski na rozszerzonej partycji obecnie jest trochę wolnego miejsca. Dla lepszego rozeznania możemy ustawić jako jednostkę sektory:
(parted) unit s
(parted) print free
Model: ATA WDC WD800JB-00JJ (scsi)
Disk /dev/sda: 156299375s
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Number Start End Size File system Name Flags
34s 2047s 2014s Free Space
1 2048s 61442047s 61440000s ntfs Microsoft basic data msftdata
2 61442048s 83970047s 22528000s Linux filesystem
3 83970048s 86067199s 2097152s linux-swap(v1) Linux swap
86067200s 86069247s 2048s Free Space
5 86069248s 106549247s 20480000s Linux filesystem
106549248s 106551295s 2048s Free Space
6 106551296s 127031295s 20480000s ext4 Linux filesystem legacy_boot
127031296s 127033343s 2048s Free Space
7 127033344s 156299263s 29265920s Linux filesystem
156299264s 156299341s 78s Free Space
albo bajty:
(parted) unit b
(parted) print free
Model: ATA WDC WD800JB-00JJ (scsi)
Disk /dev/sda: 80025280000B
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Number Start End Size File system Name Flags
17408B 1048575B 1031168B Free Space
1 1048576B 31458328575B 31457280000B ntfs Microsoft basic data msftdata
2 31458328576B 42992664575B 11534336000B Linux filesystem
3 42992664576B 44066406399B 1073741824B linux-swap(v1) Linux swap
44066406400B 44067454975B 1048576B Free Space
5 44067454976B 54553214975B 10485760000B Linux filesystem
54553214976B 54554263551B 1048576B Free Space
6 54554263552B 65040023551B 10485760000B ext4 Linux filesystem legacy_boot
65040023552B 65041072127B 1048576B Free Space
7 65041072128B 80025223167B 14984151040B Linux filesystem
80025223168B 80025263103B 39936B Free Space
Jak widać jest to 2048 sektorów albo, jak kto woli, 2048*512=1048576 bajtów i jest to wynikiem równania do 1MiB. Można te przestrzenie pokasować np. w gparted przez rozszerzenie partycji i rozciągnięcie systemu plików, jeśli to komuś przeszkadza. Można też zauważyć, że ilość wolnego miejsca na początku i końcu dysku uległa zmianie.
Sprawdźmy zatem czy zaszyfrowany linux wciąż gdzieś tam jest na dysku:
# cryptsetup luksOpen /dev/sda2 sda2_crypt
Hasło dla /dev/sda2:
# mount /dev/mapper/sda2_crypt /mnt
# ls -al /mnt
razem 136
drwxr-xr-x 28 root root 4096 sty 3 05:55 .
drwxr-xr-x 31 root root 260 sty 4 12:15 ..
drwxr-xr-x 2 root root 4096 sty 4 07:55 bin
drwxr-xr-x 2 root root 4096 sty 4 10:16 boot
lrwxrwxrwx 1 root root 11 lis 11 01:00 cdrom -> media/cdrom
drwxr-xr-x 10 root root 4096 gru 30 10:24 cgroup
drwx------ 3 root root 4096 lis 11 02:16 .config
drwxr-xr-x 2 root root 4096 sty 4 09:52 dev
drwxr-xr-x 144 root root 12288 sty 4 10:48 etc
drwxr-xr-x 5 root root 4096 gru 21 09:32 home
drwxrwxrwt 2 root root 4096 lis 11 02:54 .ICE-unix
drwxr-xr-x 18 root root 4096 gru 30 03:04 lib
drwxr-xr-x 2 root root 4096 gru 6 19:57 lib64
drwx------ 2 root root 16384 lis 11 00:11 lost+found
drwxr-xr-x 15 root root 4096 sty 4 10:14 media
drwxr-xr-x 2 root root 4096 sty 4 09:52 mnt
drwxr-xr-x 9 root root 4096 gru 27 08:08 opt
dr-xr-xr-x 2 root root 4096 sty 4 07:59 proc
drwx------ 2 root root 4096 lis 11 02:54 pulse-PKdhtXMmr18n
drwxr-xr-x 23 root root 4096 sty 4 10:27 root
drwxr-xr-x 4 root root 4096 sty 4 11:00 run
drwxr-xr-x 2 root root 12288 sty 4 07:55 sbin
drwxr-xr-x 2 root root 4096 lis 11 00:18 srv
dr-xr-xr-x 2 root root 4096 sty 4 07:59 sys
drwxrwxrwt 9 root root 4096 sty 4 11:03 tmp
drwxr-xr-x 2 root root 4096 lis 11 02:52 tmp_ram
drwxr-xr-x 11 root root 4096 lis 11 07:16 usr
drwxr-xr-x 13 root root 4096 lis 12 20:52 var
drwxrwxrwt 2 root root 4096 lis 11 02:58 .X11-unix
Wygląda na to, że przetrwał proces konwersji i nic mu nie jest. Ale to nie jest koniec naszej pracy. Trzeba jeszcze wgrać bootloader, w tym przypadku będzie to extlinux. Tworzymy zatem środowisko pod chroot i wchodzimy do systemu:
# mount -o bind /dev /mnt/dev/
# mount -o bind /dev/pts /mnt/dev/pts
# mount -o bind /sys /mnt/sys
# mount -o bind /proc /mnt/proc
# chroot /mnt
W sgdisk ustawiamy bit drugi na partycję, która zawiera katalog /boot. W moim przypadku jest to partycja 6:
# sgdisk /dev/sda --attributes=6:set:2
The operation has completed successfully.
# sgdisk /dev/sda --attributes=6:show
6:2:1 (legacy BIOS bootable)
Jeśli ktoś jest ciekawe jakie bity można ustawić, poniżej rozpiska:
# sgdisk /dev/sda --attributes=list
0: system partition
1: hide from EFI
2: legacy BIOS bootable
60: read-only
62: hidden
63: do not automount
Wgrywamy teraz MBR i VBR, tak samo jak w przypadku tablicy partycji MBR:
# dd bs=440 conv=notrunc count=1 if=/usr/lib/syslinux/gptmbr.bin of=/dev/sda
# extlinux --install /boot/extlinux/
/boot/extlinux/ is device /dev/sda6
Drugie polecenie powinno utworzyć plik ldlinux.sys w katalogu /boot/extlinux .
Po tym zabiegu można rebootnąć pc. U mnie system wystartował. Jedyne co to winxp się nie chciał odpalić i to trzeba mieć na uwadze -- winxp nie wystartuje jeśli dysk ma tablicę partycji GPT.
W drugą stronę, czyli GPT -> MBR
Konwertowanie partycji z GPT na MBR jest trochę trudniejsze. Przede wszystkim potrzebne są dziury dla rozszerzonych partycji, te same, które postały przy konwersji z MBR na GPT. Jeśli ich nie mamy na dysku, prawdopodobnie nie da rady przenieść niektórych partycji z GPT na MBR. Można je zawsze stworzyć. Trzeba pamiętać by miały 2048 sektorów. Mi dziury zostały, także wykorzystam już to co jest. Odpalamy gdiska:
# gdisk /dev/sda
GPT fdisk (gdisk) version 0.8.8
Partition table scan:
MBR: protective
BSD: not present
APM: not present
GPT: present
Found valid GPT with protective MBR; using GPT.
Command (? for help): r
Recovery/transformation command (? for help): g
Warning: 0xEE partition doesn't start on sector 1. This can cause problems
in some OSes.
I to w zasadzie tyle roboty. Podejrzymy jeszcze jak będzie wyglądał nowy układ partycji:
MBR command (? for help): p
** NOTE: Partition numbers do NOT indicate final primary/logical status,
** unlike in most MBR partitioning tools!
** Extended partitions are not displayed, but will be generated as required.
Disk size is 156299375 sectors (74.5 GiB)
MBR disk identifier: 0x00000000
MBR partitions:
Can Be Can Be
Number Boot Start Sector End Sector Status Logical Primary Code
1 2048 61442047 primary Y 0x07
2 61442048 83970047 primary Y 0x83
3 83970048 86067199 primary Y 0x82
5 86069248 106549247 logical Y 0x83
6 106551296 127031295 logical Y 0x83
7 127033344 156299263 logical Y 0x83
Jak można zauważyć są 3 podstawowe i 3 logiczne na rozszerzonej partycji. Czyli wracamy do pozycji wyjściowej. Jeśli jednak by się zdarzyło, że układ nie odpowiada naszym oczekiwaniom, możemy go zmienić. Poniżej jest lista opcji, z których możemy skorzystać:
a toggle the active/boot flag
c recompute all CHS values
l set partition as logical
o omit partition
p print the MBR partition table
q quit without saving changes
r set partition as primary
s sort MBR partitions
t change partition type code
w write the MBR partition table to disk and exit
l - ustawia logiczną partycję, r - ustawia podstawową partycję, o - nie doda partycji do tablicy MBR.
Ja potrzebowałem tylko ustawić flagę boot na 6 partycję:
MBR command (? for help): a
Toggle active flag for partition: 6
MBR command (? for help): p
Disk size is 156299375 sectors (74.5 GiB)
MBR disk identifier: 0x00000000
MBR partitions:
Can Be Can Be
Number Boot Start Sector End Sector Status Logical Primary Code
1 2048 61442047 primary Y 0x07
2 61442048 83970047 primary Y 0x83
3 83970048 86067199 primary Y 0x82
5 86069248 106549247 logical Y 0x83
6 * 106551296 127031295 logical Y 0x83
7 127033344 156299263 logical Y 0x83
MBR command (? for help): w
Converted 6 partitions. Finalize and exit? (Y/N): y
GPT data structures destroyed! You may now partition the disk using fdisk or
other utilities.
Warning: 0xEE partition doesn't start on sector 1. This can cause problems
in some OSes.
U mnie po przekonwertowaniu z GPT na MBR trzeba było zresetować pc by zobaczyć zmiany. Poniżej się prezentuje dysk, po powrocie do tablicy partycji MBR:
# parted /dev/sda
GNU Parted 2.3
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print free
Model: ATA WDC WD800JB-00JJ (scsi)
Disk /dev/sda: 80,0GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Number Start End Size Type File system Flags
32,3kB 1049kB 1016kB Free Space
1 1049kB 31,5GB 31,5GB primary ntfs
2 31,5GB 43,0GB 11,5GB primary
3 43,0GB 44,1GB 1074MB primary linux-swap(v1)
44,1GB 44,1GB 1048kB Free Space
4 44,1GB 80,0GB 36,0GB extended lba
5 44,1GB 54,6GB 10,5GB logical
6 54,6GB 65,0GB 10,5GB logical ext4 boot
7 65,0GB 80,0GB 15,0GB logical
80,0GB 80,0GB 56,8kB Free Space
Jedyna różnica to wolne 2047 sektorów przed rozszerzoną partycją. Normalnie, to wolne miejsce by było przed pierwszym dyskiem na rozszerzonej partycji. Nie wpływa to jednak na nic.
By system się zabootował prawidłowo, trzeba jeszcze zreinstalować extlinuxa, tworzymy zatem środowisko pod chroot:
# cryptsetup luksOpen /dev/sda2 sda2_crypt
Hasło dla /dev/sda2:
# mount /dev/mapper/sda2_crypt /mnt
# mount /dev/sda6 /mnt/boot/
# mount -o bind /dev/ /mnt/dev/
# mount -o bind /dev/pts /mnt/dev/pts
# mount -o bind /proc /mnt/proc
# mount -o bind /sys /mnt/sys
# chroot /mnt/
I wgrywamy MBR i VBR:
# dd bs=440 conv=notrunc count=1 if=/usr/lib/syslinux/mbr.bin of=/dev/sda
1+0 przeczytanych recordów
1+0 zapisanych recordów
skopiowane 440 bajtów (440 B), 0,0300519 s, 14,6 kB/s
# extlinux --install /boot/extlinux/
/boot/extlinux/ is device /dev/sda6
Po resecie nawet windows się odpalił. Znaczy, że wszystko wróciło do normy.